// Data validation functions for chat interface

import type { User, Message, Chat, ClientData, Tag } from './index'

// Validation result type
export interface ValidationResult {
  isValid: boolean
  errors: string[]
}

// User validation
export function validateUser(user: Partial<User>): ValidationResult {
  const errors: string[] = []

  if (!user.id || typeof user.id !== 'string' || user.id.trim().length === 0) {
    errors.push('User ID is required and must be a non-empty string')
  }

  if (!user.name || typeof user.name !== 'string' || user.name.trim().length === 0) {
    errors.push('User name is required and must be a non-empty string')
  }

  if (user.name && user.name.length > 100) {
    errors.push('User name must be less than 100 characters')
  }

  if (!user.role || !['agent', 'client'].includes(user.role)) {
    errors.push('User role must be either "agent" or "client"')
  }

  if (!user.status || !['online', 'offline', 'away'].includes(user.status)) {
    errors.push('User status must be "online", "offline", or "away"')
  }

  if (user.email && !isValidEmail(user.email)) {
    errors.push('Invalid email format')
  }

  if (user.phone && !isValidPhone(user.phone)) {
    errors.push('Invalid phone number format')
  }

  if (!user.avatar || typeof user.avatar !== 'string') {
    errors.push('User avatar is required and must be a string')
  }

  if (!user.lastSeen || !(user.lastSeen instanceof Date)) {
    errors.push('User lastSeen must be a valid Date')
  }

  if (!user.createdAt || !(user.createdAt instanceof Date)) {
    errors.push('User createdAt must be a valid Date')
  }

  if (!user.updatedAt || !(user.updatedAt instanceof Date)) {
    errors.push('User updatedAt must be a valid Date')
  }

  return {
    isValid: errors.length === 0,
    errors
  }
}

// Message validation
export function validateMessage(message: Partial<Message>): ValidationResult {
  const errors: string[] = []

  if (!message.id || typeof message.id !== 'string' || message.id.trim().length === 0) {
    errors.push('Message ID is required and must be a non-empty string')
  }

  if (!message.chatId || typeof message.chatId !== 'string' || message.chatId.trim().length === 0) {
    errors.push('Message chatId is required and must be a non-empty string')
  }

  if (!message.senderId || typeof message.senderId !== 'string' || message.senderId.trim().length === 0) {
    errors.push('Message senderId is required and must be a non-empty string')
  }

  if (!message.content || typeof message.content !== 'string') {
    errors.push('Message content is required and must be a string')
  }

  if (message.content && message.content.length > 5000) {
    errors.push('Message content must be less than 5000 characters')
  }

  if (!message.type || !['text', 'image', 'file'].includes(message.type)) {
    errors.push('Message type must be "text", "image", or "file"')
  }

  if (!message.status || !['sending', 'sent', 'delivered', 'read', 'failed'].includes(message.status)) {
    errors.push('Message status must be "sending", "sent", "delivered", "read", or "failed"')
  }

  if (!message.timestamp || !(message.timestamp instanceof Date)) {
    errors.push('Message timestamp must be a valid Date')
  }

  if (!message.createdAt || !(message.createdAt instanceof Date)) {
    errors.push('Message createdAt must be a valid Date')
  }

  if (!message.updatedAt || !(message.updatedAt instanceof Date)) {
    errors.push('Message updatedAt must be a valid Date')
  }

  // Validate metadata for file/image messages
  if (message.type === 'file' || message.type === 'image') {
    if (!message.metadata) {
      errors.push('File and image messages must have metadata')
    } else {
      if (message.type === 'file' && !message.metadata.fileName) {
        errors.push('File messages must have fileName in metadata')
      }
      if (message.metadata.fileSize && (message.metadata.fileSize <= 0 || message.metadata.fileSize > 100 * 1024 * 1024)) {
        errors.push('File size must be between 1 byte and 100MB')
      }
    }
  }

  return {
    isValid: errors.length === 0,
    errors
  }
}

// Chat validation
export function validateChat(chat: Partial<Chat>): ValidationResult {
  const errors: string[] = []

  if (!chat.id || typeof chat.id !== 'string' || chat.id.trim().length === 0) {
    errors.push('Chat ID is required and must be a non-empty string')
  }

  if (!chat.participants || !Array.isArray(chat.participants) || chat.participants.length === 0) {
    errors.push('Chat must have at least one participant')
  }

  if (chat.participants && chat.participants.length > 10) {
    errors.push('Chat cannot have more than 10 participants')
  }

  if (!chat.status || !['active', 'closed', 'pending', 'archived'].includes(chat.status)) {
    errors.push('Chat status must be "active", "closed", "pending", or "archived"')
  }

  if (chat.unreadCount !== undefined && (typeof chat.unreadCount !== 'number' || chat.unreadCount < 0)) {
    errors.push('Chat unreadCount must be a non-negative number')
  }

  if (!chat.priority || !['low', 'normal', 'high', 'urgent'].includes(chat.priority)) {
    errors.push('Chat priority must be "low", "normal", "high", or "urgent"')
  }

  if (!chat.tags || !Array.isArray(chat.tags)) {
    errors.push('Chat tags must be an array')
  }

  if (!chat.createdAt || !(chat.createdAt instanceof Date)) {
    errors.push('Chat createdAt must be a valid Date')
  }

  if (!chat.updatedAt || !(chat.updatedAt instanceof Date)) {
    errors.push('Chat updatedAt must be a valid Date')
  }

  if (chat.title && chat.title.length > 200) {
    errors.push('Chat title must be less than 200 characters')
  }

  return {
    isValid: errors.length === 0,
    errors
  }
}

// Client data validation
export function validateClientData(client: Partial<ClientData>): ValidationResult {
  const errors: string[] = []

  if (!client.id || typeof client.id !== 'string' || client.id.trim().length === 0) {
    errors.push('Client ID is required and must be a non-empty string')
  }

  if (!client.name || typeof client.name !== 'string' || client.name.trim().length === 0) {
    errors.push('Client name is required and must be a non-empty string')
  }

  if (client.name && client.name.length > 100) {
    errors.push('Client name must be less than 100 characters')
  }

  if (client.email && !isValidEmail(client.email)) {
    errors.push('Invalid email format')
  }

  if (client.phone && !isValidPhone(client.phone)) {
    errors.push('Invalid phone number format')
  }

  if (!client.language || typeof client.language !== 'string') {
    errors.push('Client language is required and must be a string')
  }

  if (!client.tags || !Array.isArray(client.tags)) {
    errors.push('Client tags must be an array')
  }

  if (!client.history || !Array.isArray(client.history)) {
    errors.push('Client history must be an array')
  }

  if (!client.customFields || typeof client.customFields !== 'object') {
    errors.push('Client customFields must be an object')
  }

  if (!client.createdAt || !(client.createdAt instanceof Date)) {
    errors.push('Client createdAt must be a valid Date')
  }

  if (!client.updatedAt || !(client.updatedAt instanceof Date)) {
    errors.push('Client updatedAt must be a valid Date')
  }

  if (client.notes && typeof client.notes !== 'string') {
    errors.push('Client notes must be a string')
  }

  if (client.notes && client.notes.length > 2000) {
    errors.push('Client notes must be less than 2000 characters')
  }

  // Validate preferences if present
  if (client.preferences) {
    if (!client.preferences.preferredLanguage) {
      errors.push('Client preferred language is required')
    }
    if (!client.preferences.communicationChannel || 
        !['chat', 'email', 'phone'].includes(client.preferences.communicationChannel)) {
      errors.push('Client communication channel must be "chat", "email", or "phone"')
    }
  }

  return {
    isValid: errors.length === 0,
    errors
  }
}

// Tag validation
export function validateTag(tag: Partial<Tag>): ValidationResult {
  const errors: string[] = []

  if (!tag.id || typeof tag.id !== 'string' || tag.id.trim().length === 0) {
    errors.push('Tag ID is required and must be a non-empty string')
  }

  if (!tag.name || typeof tag.name !== 'string' || tag.name.trim().length === 0) {
    errors.push('Tag name is required and must be a non-empty string')
  }

  if (tag.name && tag.name.length > 50) {
    errors.push('Tag name must be less than 50 characters')
  }

  if (!tag.color || typeof tag.color !== 'string' || !isValidHexColor(tag.color)) {
    errors.push('Tag color is required and must be a valid hex color')
  }

  return {
    isValid: errors.length === 0,
    errors
  }
}

// Helper validation functions
export function isValidEmail(email: string): boolean {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
  return emailRegex.test(email)
}

export function isValidPhone(phone: string): boolean {
  // Basic phone validation - accepts various formats
  const phoneRegex = /^[\+]?[1-9][\d]{0,15}$/
  const cleanPhone = phone.replace(/[\s\-\(\)]/g, '')
  return phoneRegex.test(cleanPhone) && cleanPhone.length >= 7 && cleanPhone.length <= 15
}

export function isValidHexColor(color: string): boolean {
  const hexColorRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/
  return hexColorRegex.test(color)
}

export function isValidUrl(url: string): boolean {
  try {
    new URL(url)
    return true
  } catch {
    return false
  }
}

// Batch validation function
export function validateMultiple<T>(
  items: Partial<T>[],
  validator: (item: Partial<T>) => ValidationResult
): ValidationResult {
  const allErrors: string[] = []
  let allValid = true

  items.forEach((item, index) => {
    const result = validator(item)
    if (!result.isValid) {
      allValid = false
      result.errors.forEach(error => {
        allErrors.push(`Item ${index + 1}: ${error}`)
      })
    }
  })

  return {
    isValid: allValid,
    errors: allErrors
  }
}

// Data sanitization functions
export function sanitizeString(str: string): string {
  return str.trim().replace(/\s+/g, ' ')
}

export function sanitizeHtml(html: string): string {
  // Basic HTML sanitization - remove script tags and dangerous attributes
  return html
    .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
    .replace(/on\w+="[^"]*"/gi, '')
    .replace(/javascript:/gi, '')
}

export function sanitizePhoneNumber(phone: string): string {
  return phone.replace(/[^\d\+\-\(\)\s]/g, '')
}